import { useRef, useState } from "react";
import FormInput, { FormInputProps } from "./FormInput";
import { useDebounce, useUpdateEffect } from "ahooks";

export default ({
  max,
  min,
  value,
  defaultValue,
  precision,
  onChange,

  ...rest
}: Omit<FormInputProps, "value" | "onChange"> & {
  defaultValue?: number | "";
  precision?: number;
  value?: number | ""
  min?: number;
  max?: number;
  onChange?: (e: number) => void;
}) => {

  // 用于同步value值，避免不必要的重复刷新
  const lastValue = useRef<any>()

  const [input, setInput] = useState<string | number>(defaultValue || "");
  const debouncedValue = useDebounce(input, { wait: 500 });

  // 处理数值
  const processInput = (value, precision, min, max): number | string => {
    if (value === "" || value === "-") return "";

    // 1. 使用正则表达式提取有效数字部分
    const matches = value.match(/^(-?)(\d*)(\.?\d*)/) || [];
    let [_, sign, integerPart, decimalPart] = matches;

    // 如果没有有效数字部分
    if (!integerPart && !decimalPart) {
      return sign || "";
    }

    // 处理小数部分
    let processedDecimal = "";
    if (decimalPart) {
      const decimalMatch = decimalPart.match(/^\.(\d*)/);
      if (decimalMatch) {
        // 处理precision未定义或非数值的情况
        const decimalDigits =
          typeof precision === "number"
            ? decimalMatch[1].substring(0, precision)
            : decimalMatch[1];
        processedDecimal = "." + (decimalDigits || "");
      }
    }

    // 组合结果
    let result = sign + (integerPart || "0") + processedDecimal;

    // 处理特殊情况
    if (result === "-.") result = "-0.";
    if (result === ".") result = "0.";

    // 转换为数字进行范围检查
    const numericValue = Number(result);

    // 处理min/max限制
    if (typeof min === "number" && numericValue < min) {
      return min;
    }
    if (typeof max === "number" && numericValue > max) {
      return max;
    }

    return result;
  };

  useUpdateEffect(() => {
    if (value !== lastValue.current) {
      setInput(value as string | number)
      lastValue.current = value
    }
  }, [value])

  useUpdateEffect(() => {

    if (input !== lastValue.current) {
      let val = processInput(debouncedValue, precision, min, max);
      setInput(val);
      //
      val = val === '-' ? 0 : Number(val)
      lastValue.current = val
      onChange?.(val);
    }
  }, [debouncedValue]);

  return (
    <FormInput {...rest} value={input + ""} type="digit" onChange={setInput} />
  );
};
